package ru.spb.osll.myfit.server.execute;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import ru.spb.osll.myfit.common.ProgressCounts;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.server.log.Log;
import ru.spb.osll.myfit.server.parser.TableParser;
import fit.Counts;
import fit.Parse;

public class FixtureListenerImpl implements ProgressFixtureListener {
	private List<Table> m_tables = new LinkedList<Table>();
	private TableParser m_tableParser;
	private ProgressCounts m_counts;
	private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

	public FixtureListenerImpl(TableParser tableParser) {
		m_tableParser = tableParser;
		m_counts = new ProgressCounts();
	}

	@Override
	public void tableFinished(Parse table) {
		Table newTable = m_tableParser.parse(table);
		if (newTable != null) {
			m_tables.add(newTable);
			m_counts.setProgressSegments(m_counts.getProgressSegments() + 1);
		}
		
		try {
      byte[] bytes = readTable(table);
      if (bytes.length > 0) {
        outputStream.write(bytes);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
	}

	@Override
	public void tablesFinished(Counts arg0) {
		Log.log.info("Counts: " + arg0.toString());
	}

	public List<Table> getTables() {
		return Collections.unmodifiableList(m_tables);
	}

	public void setCounts(Counts counts) {
		m_counts.setCounts(counts.right, counts.wrong, counts.ignores,
				counts.exceptions);
	}

	public ProgressCounts getCounts() {
		return m_counts;
	}

	public void countTotalTablesQuantity(Parse tables) {
		int totalTables = 0;
		Table newTable;
		tables = tables.more;
		while (tables != null) {
			newTable = m_tableParser.parse(tables);
			if (newTable != null) {
				totalTables++;
			}
			tables = tables.more;
		}
		m_counts.setTotalSegments(totalTables);
	}

	private byte[] readTable(Parse table) throws IOException {
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    OutputStreamWriter streamWriter = new OutputStreamWriter(
        byteBuffer, "UTF-8");
    PrintWriter writer = new PrintWriter(streamWriter);
    Parse more = table.more;
    table.more = null;
    if (table.trailer == null)
      table.trailer = "";
    table.print(writer);
    table.more = more;
    writer.close();
    return byteBuffer.toByteArray();
  }
	
	public ByteArrayOutputStream getOutputStream() {
	  return outputStream;
	}
}
